package base;

import db.IPersistable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * Manages the user information
 * @author Shayan
 */
public class User extends Entity implements IPersistable {

    public User() {
        this.dateOfBirth = new Date();
    }

    public User(String id, String name, String password) {
        setId(id);
        this.name = name;
        this.password = password;
        this.dateOfBirth = new Date();
    }
    /**
     * Name
     */
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    /**
     * Password
     */
    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    /**
     * Date of Birth
     */
    private Date dateOfBirth;

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
    /**
     * Weight
     */
    public float weight;

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }
    /**
     * Hieght
     */
    public float height;

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }
    /**
     * Sex
     */
    private boolean sex;

    public boolean getSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }
    /**
     * Target weight
     */
    public float targetWeight;

    public float getTargetWeight() {
        return targetWeight;
    }

    public void setTargetWeight(float targetWeight) {
        this.targetWeight = targetWeight;
    }

    /**
     * Validate
     */
    public void validate() throws ValidationException {
        if (weight <= 0) {
            throw new ValidationException("weight cannot be less than or equal to zero");
        }

        if (height <= 0) {
            throw new ValidationException("length cannot be less than or equal to zero");
        }
    }

    public byte[] getData() throws IOException {
        ByteArrayOutputStream bin = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bin);
        out.writeUTF(getId());
        out.writeUTF(name);
        out.writeUTF(password);
        out.writeBoolean(sex);
        out.writeLong(dateOfBirth.getTime());
        out.writeFloat(weight);
        out.writeFloat(height);
        out.writeFloat(targetWeight);

        out.flush();
        return bin.toByteArray();
    }

    public static User create(byte[] data) throws IOException {
        User user = new User();

        ByteArrayInputStream bin = new ByteArrayInputStream(data);
        DataInputStream in = new DataInputStream(bin);

        user.setId(in.readUTF());
        user.setName(in.readUTF());
        user.setPassword(in.readUTF());
        user.setSex(in.readBoolean());
        user.setDateOfBirth(new Date(in.readLong()));
        user.setWeight(in.readFloat());
        user.setHeight(in.readFloat());
        user.setTargetWeight(in.readFloat());
        return user;
    }

    public float getBMR() {
        return Calculator.getBMR(sex, height, weight, dateOfBirth);
    }
}
